import { Subject } from 'rxjs';
import {
  DynamicInstanceConfig,
  IPSAppDataEntity,
  IPSDEListDataItem,
  IPSDEMobMDCtrl,
  IPSDEUIAction,
  IPSUIAction,
  IPSUIActionGroupDetail,
} from '@ibiz/dynamic-model-api';
import { ModelTool, Util, ViewTool } from '../../../util';
import {
  MobMDCtrlEvents,
  IUIDataParam,
  IMobMDCtrlController,
  ICtrlActionResult,
  IViewStateParam,
  IParam,
} from '../../../interface';
import { AppMDCtrlController } from './app-md-ctrl-controller';
import { AppMobMDCtrlService } from '../../ctrl-service/app-mob-mdctrl-service';

export class MobMDCtrlController extends AppMDCtrlController implements IMobMDCtrlController {
  /**
   * @description 移动端多数据部件实例对象
   * @type {IPSDEMobMDCtrl}
   * @memberof MobMDCtrlController
   */
  public controlInstance!: IPSDEMobMDCtrl;

  /**
   * @description 单选选择值
   * @private
   * @type {string}
   * @memberof MobMDCtrlController
   */
  private selectedValue: string = '';

  /**
   * @description 是否需要加载更多
   * @readonly
   * @type {boolean}
   * @memberof MobMDCtrlController
   */
  get needLoadMore(): boolean {
    return (this.curPage + 1) * this.limit >= this.totalRecord ? false : true;
  }

  /**
   * @description 多数据部件模型数据加载
   * @memberof MobMDCtrlController
   */
  public async ctrlModelLoad() {
    await super.ctrlModelLoad();
    if (!App.isPreviewMode()) {
      //  实体服务
      this.ctrlService = new AppMobMDCtrlService(this.controlInstance);
      await this.ctrlService.loaded();
    }
  }

  /**
   * @description 初始化数据映射
   * @memberof MobMDCtrlController
   */
  public initDataMap() {
    const dataItems: IPSDEListDataItem[] | null = this.controlInstance.getPSDEListDataItems();
    if (dataItems && dataItems.length > 0) {
      dataItems.forEach((dataItem: IPSDEListDataItem) => {
        this.dataMap.set(dataItem.name,{ customCode: dataItem.customCode ? true : false });
      });
    }
  }

  /**
   * @description 部件初始化
   * @param {IParam} [args] 初始化参数
   * @memberof MobMDCtrlController
   */
  public ctrlInit(args?: IParam) {
    super.ctrlInit(args);
    if (this.viewState) {
      this.viewStateEvent = this.viewState.subscribe(({ tag, action, data = {} }: IViewStateParam) => {
        if (!Object.is(this.name, tag)) {
          return;
        }
        if (Object.is(action, 'load')) {
          this.curPage = 0;
          this.load(data);
        }
        if (Object.is(action, 'search')) {
          this.curPage = 0;
          this.load(data);
        }
        if (Object.is(action, 'quickSearch')) {
          this.load(data);
        }
      });
    }
  }

  /**
   * @description 删除
   * @param {IParam[]} datas 要删除的数据集合
   * @param {IParam} [args] 行为参数
   * @param {boolean} [showInfo=true] 是否显示提示信息
   * @param {boolean} [loadding=true] 是否显示loadding效果
   * @return {*}  {Promise<any>}
   * @memberof MobMDCtrlController
   */
  public async remove(
    datas: IParam[],
    args?: IParam,
    showInfo: boolean = true,
    loadding: boolean = true,
  ): Promise<any> {
    const arg: any = {};
    const keys: Array<string> = [];
    let infoStr: string = '';
    const appDataEntity = this.controlInstance.getPSAppDataEntity() as IPSAppDataEntity;
    datas.forEach((data: any, index: number) => {
      keys.push(data[appDataEntity.codeName.toLowerCase()]);
      if (index < 5) {
        if (!Object.is(infoStr, '')) {
          infoStr += '、';
        }
        const majorField: any = ModelTool.getAppEntityMajorField(appDataEntity);
        infoStr += data[majorField];
      }
    });
    if (datas.length <= 0) {
      App.getNoticeService().error('至少选择一条数据');
      return { ret: false, data: this.items };
    }
    if (datas.length < 5) {
      infoStr = `${infoStr} 共 ${datas.length} 条数据`;
    } else {
      infoStr = `${infoStr}... 共 ${datas.length} 条数据`;
    }
    const _remove = async () => {
      const _context: any = { [appDataEntity.codeName.toLowerCase()]: keys.join(';') };
      const tempContext: any = Util.deepCopy(this.context);
      Object.assign(tempContext, _context);
      this.onControlRequset('remove', tempContext, arg, loadding);
      const response: any = await this.ctrlService.delete(this.removeAction, tempContext, arg, loadding);
      this.onControlResponse('remove', response);
      if (response && response.status === 200 && response.data) {
        if (showInfo) {
          App.getNoticeService().success('删除成功');
        }
        return await this.load();
      } else {
        if (showInfo) {
          App.getNoticeService().error(response?.error?.message || '删除失败');
        }
        return { ret: false, data: response.data };
      }
    };
    const confirm: Subject<string> | null = App.getMsgboxService().open({
      title: '警告',
      content: `是否确认删除 ${infoStr}`,
    });
    if (confirm) {
      confirm.subscribe(async (result: string) => {
        if (result == 'ok') {
          return await _remove();
        } else {
          return { ret: false, data: this.items };
        }
      });
    }
  }

  /**
   * @description 刷新数据
   * @param {IParam} opts 行为参数
   * @param {IParam} [args] 额外行为参数
   * @param {boolean} [showInfo] 是否显示提示
   * @param {boolean} [loadding] 是否显示loadding效果
   * @return {*}  {Promise<ICtrlActionResult>}
   * @memberof MobMDCtrlController
   */
  public async refresh(
    opts: IParam,
    args?: IParam,
    showInfo?: boolean,
    loadding?: boolean,
  ): Promise<ICtrlActionResult> {
    this.curPage = 0;
    return await this.load(opts, args, this.showBusyIndicator, loadding);
  }

  /**
   * @description 数据加载
   * @param {IParam} [opts] 行为参数
   * @param {boolean} [showInfo=true] 是否显示提示信息
   * @param {boolean} [loadding=true] 是否
   * @param {*} [args]
   * @return {*}  {Promise<ICtrlActionResult>}
   * @memberof MobMDCtrlController
   */
  public async load(
    opts?: IParam,
    args?: IParam,
    showInfo: boolean = true,
    loadding: boolean = true,
  ): Promise<ICtrlActionResult> {
    const tempViewParams: any = {};
    // 合并page，size
    Object.assign(tempViewParams, {
      page: this.curPage,
      size: this.limit,
    });
    // 合并sort
    if (this.sort) {
      Object.assign(tempViewParams, this.sort);
    }
    Object.assign(tempViewParams, Util.deepCopy(opts));
    Object.assign(tempViewParams, Util.deepCopy(this.viewParam));
    opts ? opts : opts = {};
    Object.assign(opts, { viewParam: tempViewParams });
    // 多实例查询数据处理
    const appEnvironment = App.getEnvironment();
    if (appEnvironment?.bDynamic) {
      if (tempViewParams.hasOwnProperty('srfdynainstid')) {
        const dynainstParam: DynamicInstanceConfig = this.modelService?.getDynaInsConfig();
        Object.assign(tempViewParams, { srfinsttag: dynainstParam.instTag, srfinsttag2: dynainstParam.instTag2 });
        delete tempViewParams.srfdynainstid;
      } else {
        if (!tempViewParams.hasOwnProperty('srfinsttag')) {
          Object.assign(tempViewParams, { srfinsttag: '__srfstdinst__' });
        }
      }
    } else {
      if (tempViewParams.hasOwnProperty('srfwf')) {
        Object.assign(tempViewParams, { srfinsttag: '__srfstdinst__' });
      }
    }
    const tempContext: any = Util.deepCopy(this.context);
    const beforeUIDataParam: IUIDataParam = this.getUIDataParam();
    Object.assign(beforeUIDataParam, {
      action: this.fetchAction,
      navContext: tempContext,
      navParam: opts,
      data: this.items,
    });
    const beforeloadResult: any = await this.executeCtrlEventLogic('onbeforeload', beforeUIDataParam);
    if (beforeloadResult && beforeloadResult?.hasOwnProperty('srfret') && !beforeloadResult.srfret) {
      return { ret: false, data: this.items };
    }
    this.ctrlEvent(MobMDCtrlEvents.BEFORE_LOAD, beforeUIDataParam);
    this.onControlRequset('load', { ...this.context }, opts, loadding);
    try {
      const response = await this.ctrlService.search(this.fetchAction, this.context, opts, showInfo);
      this.onControlResponse('load', response);
      if (response && response.status == 200) {
        const successUIDataParam: IUIDataParam = this.getUIDataParam();
        Object.assign(successUIDataParam, {
          action: this.fetchAction,
          navContext: tempContext,
          navParam: opts,
          data: response.data,
        });
        const loadsuccessResult: any = await this.executeCtrlEventLogic('onloadsuccess', successUIDataParam);
        if (loadsuccessResult && loadsuccessResult?.hasOwnProperty('srfret') && !loadsuccessResult.srfret) {
          return { ret: false, data: response.data };
        }
        this.ctrlEvent(MobMDCtrlEvents.LOAD_SUCCESS, successUIDataParam);
        this.totalRecord = response.total;
        if (args?.type == 'loadMore') {
          if (response.data?.length) {
            const tempItems = this.items;
            this.items = [];
            this.items = tempItems.concat(response.data);
          }
        } else {
          this.items = [];
          this.items = response.data;
        }
        // 将选中数据补充完整
        if (this.selections?.length > 0) {
          const selections: any[] = [];
          this.selections.forEach((selection: any) => {
            const _selection = this.items.find((item: any) => Object.is(selection.srfkey, item.srfkey));
            if (_selection) {
              selections.push(_selection);
            }
          });
          this.selections = selections;
        }
        this.items.forEach((item: any) => {
          // 计算是否选中
          const index = this.selections.findIndex((temp: any) => {
            return temp.srfkey == item.srfkey;
          });
          if (index != -1 || Object.is(this.selectedValue, item.srfkey)) {
            item.checked = true;
          } else {
            item.checked = false;
          }
          Object.assign(item, this.getActionState(item));
          // 计算权限
          this.computeSlidingDisabled(item);
        });
        if (this.isEnableGroup) {
          this.getGroupData();
        }
      } else {
        const errorUIDataParam: IUIDataParam = this.getUIDataParam();
        Object.assign(errorUIDataParam, {
          action: this.fetchAction,
          navContext: tempContext,
          navParam: opts,
          data: response.data,
        });
        const loaderrorResult: any = await this.executeCtrlEventLogic('onloaderror', errorUIDataParam);
        if (loaderrorResult && loaderrorResult?.hasOwnProperty('srfret') && !loaderrorResult.srfret) {
          return { ret: false, data: response.data };
        }
        this.ctrlEvent(MobMDCtrlEvents.LOAD_ERROR, errorUIDataParam);
        App.getNoticeService().error(response.error?.message || '加载数据异常');
      }
      return { ret: true, data: response.data };
    } catch (error: any) {
      this.onControlResponse('load', error);
      const errorUIDataParam: IUIDataParam = this.getUIDataParam();
      Object.assign(errorUIDataParam, {
        action: this.fetchAction,
        navContext: tempContext,
        navParam: opts,
        data: [error.data],
      });
      const loaderrorResult: any = await this.executeCtrlEventLogic('onloaderror', errorUIDataParam);
      if (loaderrorResult && loaderrorResult?.hasOwnProperty('srfret') && !loaderrorResult.srfret) {
        return { ret: false, data: error.data };
      }
      this.ctrlEvent(MobMDCtrlEvents.LOAD_ERROR, errorUIDataParam);
      if (showInfo) {
        App.getNoticeService().error(error.error?.message || '加载数据异常');
      }
      return { ret: false, data: error.data };
    }
  }

  /**
   * @description 获取界面行为权限状态
   * @private
   * @param {*} data 数据
   * @return {*}
   * @memberof MobMDCtrlController
   */
  private getActionState(data: any) {
    const tempActionModel: any = Util.deepCopy(this.actionModel);
    ViewTool.calcActionItemAuthState(data, tempActionModel, this.appUIService);
    return tempActionModel;
  }

  /**
   * @description 初始化界面行为模型
   * @memberof MobMDCtrlController
   */
  public initCtrlActionModel() {
    //  左滑界面行为集合
    const swipeLeftActionGroupDetails =
      this.controlInstance.getPSDEUIActionGroup?.()?.getPSUIActionGroupDetails?.() || [];
    swipeLeftActionGroupDetails.forEach((detail: IPSUIActionGroupDetail) => {
      const uiAction = detail.getPSUIAction() as IPSUIAction;
      this.actionModel[uiAction.uIActionTag] = this.getCtrlActionModelDetail(detail);
    });

    //  右滑界面行为集合
    const swipeRightActionGroupDetails =
      this.controlInstance.getPSDEUIActionGroup2?.()?.getPSUIActionGroupDetails?.() || [];
    swipeRightActionGroupDetails.forEach((detail: IPSUIActionGroupDetail) => {
      const uiAction = detail.getPSUIAction() as IPSUIAction;
      const actionModelDetail: any = this.getCtrlActionModelDetail(detail);
      Object.assign(actionModelDetail, {
        isShowCaption: detail.showCaption,
        isShowIcon: detail.showIcon,
      });
      this.actionModel[uiAction.uIActionTag] = actionModelDetail;
    });
  }

  /**
   * @description 初始化界面行为组成员模型
   * @private
   * @param {IPSUIActionGroupDetail} detail 行为组成员模型
   * @return {*}
   * @memberof MobMDCtrlController
   */
  private getCtrlActionModelDetail(detail: IPSUIActionGroupDetail) {
    const item = detail.getPSUIAction() as IPSUIAction;
    const tempData: any = {
      name: item.uIActionTag,
      disabled: false,
      visabled: true,
      noprivdisplaymode: (item as IPSDEUIAction)?.noPrivDisplayMode,
      dataaccaction: item?.dataAccessAction,
      target: item?.actionTarget,
      icon: item?.getPSSysImage()?.cssClass,
      isShowCaption: true,
      isShowIcon: true,
    };
    return tempData;
  }

  /**
   * @description 计算列表项左滑右滑禁用状态
   * @private
   * @param {IParam} item 项数据
   * @memberof MobMDCtrlController
   */
  private computeSlidingDisabled(item: IParam) {
    item.sliding_disabled = true;
    Object.keys(this.actionModel).forEach((key, index) => {
      if (item[key].visabled && item.sliding_disabled) {
        item.sliding_disabled = false;
      }
    });
  }

  /**
   * @description 选中数据改变
   * @param {any[]} selections 选中数组
   * @memberof MobMDCtrlController
   */
  public selectionChange(selections: any[]) {
    this.selections = selections;
    const UIDataParams = this.getUIDataParam();
    Object.assign(UIDataParams, { data: this.selections });
    this.ctrlEvent(MobMDCtrlEvents.SELECT_CHANGE, UIDataParams);
  }

  /**
   * @description 项选中
   * @param {*} item 项数据
   * @param {*} event 事件源
   * @memberof MobMDCtrlController
   */
  public onRowSelect(item: any, event: MouseEvent) {
    if (this.isMultiple) {
      const count = this.selections.findIndex((temp: any) => {
        return temp.mobentityid == item.mobentityid;
      });
      if (count === -1) {
        this.selections.push(item);
      } else {
        this.selections.splice(count, 1);
      }
    } else {
      const selectUIParam: IUIDataParam = this.getUIDataParam();
      Object.assign(selectUIParam, { data: [item], event: event });
      this.ctrlEvent(MobMDCtrlEvents.ROW_SELECTED, selectUIParam);
    }
  }

  /**
   * @description 上拉加载更多数据
   * @return {*}  {Promise<ICtrlActionResult>}
   * @memberof MobMDCtrlController
   */
  public async loadBottom(): Promise<ICtrlActionResult> {
    if (!this.needLoadMore) {
      return { ret: false, data: this.items };
    }
    this.curPage++;
    const params = {};
    if (this.viewParam) {
      Object.assign(params, this.viewParam);
    }
    Object.assign(params, { page: this.curPage, size: this.limit });
    return await this.load(params, { type: 'loadMore' }, this.showBusyIndicator, false);
  }
}
